module elevator(
input clk,
input rst,//输入时注意，rst默认一定要为1，为0会卡状态
input [4:0] in_req,
input [4:0] out_requp,
input [4:0] out_reqdown,
input wire key_open,

input clk1,

output reg [4:0] cur_floor,//also notice that out_request 
output reg up,					//should be divided into out_request_up 
output reg down,				//and out_request_down
output reg stop, //1 -> open,0 -> shut up
output reg [4:0] in_reqN,
output reg [4:0] out_requpN,
output reg [4:0] out_reqdownN
);


reg [4:0] total_requp;
reg [4:0] total_reqdown;
reg [4:0] total;

//elevator 1
parameter F1UP          = 7'b0100001;
parameter F1UP_OPEN     = 7'b1100001;
parameter F2UP          = 7'b0100010;
parameter F2UP_OPEN     = 7'b1100010;
parameter F2DOWN        = 7'b0000010;
parameter F2DOWN_OPEN   = 7'b1000010;
parameter F3UP          = 7'b0100100;
parameter F3UP_OPEN     = 7'b1100100;
parameter F3DOWN        = 7'b0000100;
parameter F3DOWN_OPEN   = 7'b1000100;
parameter F4UP          = 7'b0101000;
parameter F4UP_OPEN     = 7'b1101000;
parameter F4DOWN        = 7'b0001000;
parameter F4DOWN_OPEN   = 7'b1001000;
parameter F5DOWN        = 7'b0110000;
parameter F5DOWN_OPEN   = 7'b1010000;

parameter F1DOWN		   = 7'b0000001;///

reg [6:0] current_state, next_state;

initial
    begin
       up <= 1'b0;
       down <= 1'b0;
       stop <= 1'b0;
       cur_floor <= 5'b00001;
		 current_state <= F1UP;
    end

	 

	 
	 
//第一段
always @ (posedge clk or negedge rst)
   if (!rst)
        current_state <= F1UP;
	 else
		begin
        current_state <= next_state;
		  total_requp <= in_req | out_requp;
		  total_reqdown <= in_req | out_reqdown;
		  total <= in_req | out_requp | out_reqdown;
		end 
		  
//根据条件转移状态
always@(posedge clk1)
    begin
	 
    case (current_state)
	 
	 F1UP : if (total_requp[0] == 1)
					next_state <= F1UP_OPEN;
			  else if (total > 5'b00001)
					next_state <= F2UP;
			  else if (total == 5'b00000)
					next_state <= F1UP;
					
	 F1UP_OPEN : 
					 if (key_open == 0)
							next_state <= F1UP_OPEN;
					 else if (total > 5'b00001)
							next_state <= F2UP;
					 else if (total == 5'b00000)
							next_state <= F1UP;
							
	 F2UP : if (total_requp[1] == 1)
					next_state <= F2UP_OPEN;
			  else if (total[4:1] > 4'b0001)
					next_state <= F3UP;
			  else if (total_reqdown[1] ==1)
					next_state <= F2DOWN_OPEN;
			  else next_state <= F1DOWN;//+++
					
	 F2UP_OPEN : if (key_open == 0)
							next_state <= F2UP_OPEN;
					 else if (total[4:1] > 4'b0001)
							next_state <= F3UP;
					 else if (total < 5'b00010)
							next_state <= F1DOWN;//
					 else next_state <= F2DOWN_OPEN;///
					
	 F3UP : if (total_requp[2] == 1)
					next_state <= F3UP_OPEN;
			  else if (total[4:2] > 3'b001)
					next_state <= F4UP;
			  else if (total_reqdown[2] ==1)
					next_state <= F3DOWN_OPEN;
			  else next_state <= F2DOWN;
					
	 F3UP_OPEN : if (key_open == 0)
							next_state <= F3UP_OPEN;
					 else if (total[4:2] > 3'b001)
							next_state <= F4UP;
					 else if (total < 5'b00100)
							next_state <= F2DOWN;//
					 else next_state <= F3DOWN_OPEN;///
						
	 F4UP : if (total_requp[3] == 1)
					next_state <= F4UP_OPEN;
			  else if (total[4:3] > 2'b01)
					next_state <= F5DOWN;
			  else if (total_reqdown[3] ==1)
					next_state <= F4DOWN_OPEN;
			  else next_state <= F3DOWN;
					
	 F4UP_OPEN : if (key_open == 0)
							next_state <= F4UP_OPEN;
					 else if (total[4:3] > 2'b01)
							next_state <= F5DOWN;
					 else if (total < 5'b01000)
							next_state <= F3DOWN;//
					 else next_state <= F4DOWN_OPEN;///
							
	 F5DOWN : if (total_reqdown[4] == 1)
						next_state <= F5DOWN_OPEN;
				 else if (total_reqdown < 5'b10000)
						next_state <= F4DOWN;
						
	 F5DOWN_OPEN : if (key_open == 0)
							next_state <= F5DOWN_OPEN;
						else if (total < 5'b10000)
							next_state <= F4DOWN;//**
							
	 F4DOWN : if (total_reqdown[3] == 1)
						next_state <= F4DOWN_OPEN;
				 else if (total_reqdown[2:0] == 3'b000 && total[4:3] > 2'b01)
						next_state <= F5DOWN;//+++
				 else if (total_reqdown[3:0] < 4'b1000)
						next_state <= F3DOWN;
							
	 F4DOWN_OPEN : if(key_open == 0)
							next_state <= F4DOWN_OPEN;
						else if (total_reqdown[2:0] == 3'b000 && total[4:3] > 2'b01)
							next_state <= F5DOWN;//+++
						else if (total_reqdown[3:0]<4'b1000)
							next_state <= F3DOWN;//F3DOWN
						else next_state <= F4UP_OPEN;///

							
	 F3DOWN : if (total_reqdown[2] == 1)
						next_state <= F3DOWN_OPEN;
				 else if (total_reqdown[1:0] == 2'b00 && total[4:2] > 3'b001)
						next_state <= F4UP;//+++
				 else if (total_reqdown[2:0] < 3'b100)
						next_state <= F2DOWN;
				 
							
	 F3DOWN_OPEN : if(key_open == 0)
							next_state <= F3DOWN_OPEN;
						else if (total_reqdown[1:0] == 2'b00 && total[4:2] > 3'b001)
							next_state <= F4UP;//+++
						else if (total_reqdown[2:0]<3'b100)
							next_state <= F2DOWN;//F2DOWN
						else next_state <= F3UP_OPEN;///
						
							
	 F2DOWN : if (total_reqdown[1] == 1)
						next_state <= F2DOWN_OPEN;
				 else if (total_reqdown[0] == 0 && total[4:1] > 4'b0001)
						next_state <= F3UP;//+++
				 else if (total_reqdown[1:0] <2'b10)//+++
						next_state <= F1DOWN;//**
			    
							
	 F2DOWN_OPEN : if(key_open == 0)
							next_state <= F2DOWN_OPEN;
						else if (total_reqdown[0] == 0 && total[4:1] > 4'b0001)
							next_state <= F3UP;//+++
						else if (total_reqdown[1:0]<2'b10)
							next_state <= F1DOWN;//**
						else next_state <= F2UP_OPEN;///
							
	 F1DOWN : if (total_requp[0] == 1)  
					next_state <= F1UP_OPEN;
			    else if (total > 5'b00001)
					next_state <= F2UP;
			    else if (total == 5'b00000)
					next_state <= F1UP;

							
						
   default : next_state <= F1UP;
	 
	 endcase
	 
    end

//always@(posedge clk or negedge rst)

//第三段
always@(current_state)
	begin
		case (current_state)
		F1UP : begin
				cur_floor <= 5'b00001;
				up <= 0;///
				down <= 0;
				stop <= 0;
				in_reqN <= 5'b11111;
				out_requpN <= 5'b11111;
				out_reqdownN <= 5'b11111;
				end
				
		F2UP : begin
				cur_floor <= 5'b00010;
				up <= 1;
				down <= 0;
				stop <= 0;
				in_reqN <= 5'b11111;
				out_requpN <= 5'b11111;
				out_reqdownN <= 5'b11111;
				end
				
		F3UP : begin
				cur_floor <= 5'b00100;
				up <= 1;
				down <= 0;
				stop <= 0;
				in_reqN <= 5'b11111;
				out_requpN <= 5'b11111;
				out_reqdownN <= 5'b11111;
				end
				
		F4UP : begin
				cur_floor <= 5'b01000;
				up <= 1;
				down <= 0;
				stop <= 0;
				in_reqN <= 5'b11111;
				out_requpN <= 5'b11111;
				out_reqdownN <= 5'b11111;
				end
				
		F5DOWN : begin
				cur_floor <= 5'b10000;
				up <= 1;
				down <= 0;
				stop <= 0;
				in_reqN <= 5'b11111;
				out_requpN <= 5'b11111;
				out_reqdownN <= 5'b11111;
				end
				
		F4DOWN : begin
				cur_floor <= 5'b01000;
				up <= 0;
				down <= 1;
				stop <= 0;
				in_reqN <= 5'b11111;
				out_requpN <= 5'b11111;
				out_reqdownN <= 5'b11111;
				end
				
		F3DOWN : begin
				cur_floor <= 5'b00100;
				up <= 0;
				down <= 1;
				stop <= 0;
				in_reqN <= 5'b11111;
				out_requpN <= 5'b11111;
				out_reqdownN <= 5'b11111;
				end
				
		F2DOWN : begin
				cur_floor <= 5'b00010;
				up <= 0;
				down <= 1;
				stop <= 0;
				in_reqN <= 5'b11111;
				out_requpN <= 5'b11111;
				out_reqdownN <= 5'b11111;
				end
				
		F1UP_OPEN : begin
				cur_floor <= 5'b00001;
				up <= 1;
				down <= 0;
				stop <= 1;
				in_reqN[0] <= 0;
				out_requpN[0] <= 0;
						end
		
		F2UP_OPEN : begin
				cur_floor <= 5'b00010;
				up <= 1;
				down <= 0;
				stop <= 1;
				in_reqN[1] <= 0;
				out_requpN[1] <= 0;
						end
						
		F3UP_OPEN : begin
				cur_floor <= 5'b00100;
				up <= 1;
				down <= 0;
				stop <= 1;
				in_reqN[2] <= 0;
				out_requpN[2] <= 0;
						end
						
		F4UP_OPEN : begin
				cur_floor <= 5'b01000;
				up <= 1;
				down <= 0;
				stop <= 1;
				in_reqN[3] <= 0;
				out_requpN[3] <= 0;
						end
						
		F5DOWN_OPEN : begin
				cur_floor <= 5'b10000;
				up <= 0;
				down <= 1;
				stop <= 1;
				in_reqN[4] <= 0;
				out_reqdownN[4] <= 0;
						end
						
		F4DOWN_OPEN : begin
				cur_floor <= 5'b01000;
				up <= 0;
				down <= 1;
				stop <= 1;
				in_reqN[3] <= 0;
				out_reqdownN[3] <= 0;
						end
				
		F3DOWN_OPEN : begin
				cur_floor <= 5'b00100;
				up <= 0;
				down <= 1;
				stop <= 1;
				in_reqN[2] <= 0;
				out_reqdownN[2] <= 0;
							end
				
		F2DOWN_OPEN : begin
				cur_floor <= 5'b00010;
				up <= 0;
				down <= 1;
				stop <= 1;
				in_reqN[1] <= 0;
				out_reqdownN[1] <= 0;
							end
							
		F1DOWN : begin
				cur_floor <= 5'b00001;
				up <= 0;///
				down <= 1;
				stop <= 0;
				in_reqN <= 5'b11111;
				out_requpN <= 5'b11111;
				out_reqdownN <= 5'b11111;
				end
				
				
		endcase
	end		

	

endmodule
